<!--
 * @title: 用户参照
 * @params1: singleSelect 默认false 是否单选，true为单选，false为多选
 * @params2: dataType 默认id 传入和传出的字段，可选值id或code，若为code，则v-mode的值为code1,code2,code3的形式，id为id1,id2,id3的形式
 * @params3: value v-model绑定的值，打开参照可绑定value值为默认值，选择后，会返回value的值，value值类型根据dataType选择
 * @params4: initDisplayData 初始显示值，比如dispuserid
 * @params5: isDisplayDefaultElement 是否显示默认的选择元素
 * @params6: disabled 禁用
 * @params7: deptLazy 是否懒加载部门列表，true表示先只加载第一级部门节点，展开后加载下级
 * @params8: width 默认input框的宽度
 * @method1: confirm 用户选择后，返回选择的cboUser对象的数组
 * @slot1: default 可替换默认的选择框元素
 * @slot2: search 可替换默认的搜索条件，带有queryUserParam
 * @description: 用户参照选择组件
 * @filterDimission: 过滤掉离职人员与失效部门
 * @fileName: RefUser.vue
 * @author: zhanglongfei
 * @date: 2019-08-24 14:00:17
!-->
<template>
  <div>
    <slot>
      <el-input v-model="initDisplayData" :style="{ width: width }" :readonly="true" :disabled="true" class="tl-ref-selector" :class="{ disabled: disabled }" v-if="isDisplayDefaultElement">
        <el-button slot="append" icon="el-icon-search" @click="openRefDialog" :disabled="disabled"></el-button>
      </el-input>
    </slot>
    <el-dialog :visible.sync="refVisible" ref="refDailog" :title="refTitle" :close-on-click-modal="false" v-dialogDrag width="900px" :modal-append-to-body="false" :append-to-body="true" top="20px" class="tl-ref tl-dialog tl-ref-user" @open="open">
      <el-row class="top-category">
        <el-col :span="9">
          <el-tabs v-model="activeName" @tab-click="tabClick">
            <el-tab-pane name="dept">
              <span slot="label"><i class="el-icon-school"></i> 部门</span>
              <el-input v-model="deptFilterName" style="width:100%;" :placeholder="deptLazy ? '筛选暂不可用' : '请输入名称筛选'" @keyup.enter.native="filterDept" :disabled="deptLazy">
                <el-button slot="append" icon="el-icon-search" @click="filterDept"></el-button>
              </el-input>
              <el-scrollbar class="scroll-category">
                <el-tree class="tl-tree" ref="deptTree" v-loading="deptTreeLoading" :lazy="deptLazy" :load="deptLazyLoad" :props="deptTreeProps" :data="deptList" node-key="id" :expand-on-click-node="false" empty-text="暂无部门信息" :default-expanded-keys="[0]" highlight-current @node-click="doQueryByDept" :filter-node-method="filterDeptNode"> </el-tree>
              </el-scrollbar>
            </el-tab-pane>
            <el-tab-pane name="role" :lazy="true">
              <span slot="label"><i class="el-icon-user"></i> 角色</span>
              <el-input v-model="roleFilterName" style="width:100%;" placeholder="请输入名称筛选">
                <el-button slot="append" icon="el-icon-search"></el-button>
              </el-input>
              <el-scrollbar class="scroll-category">
                <ul class="role-list">
                  <li v-for="role in fileterRoleList" :key="role.id" @click="doQueryByRole(role)" :class="{ selected: role.id === queryUserParam.qry_roleid }"><i class="el-icon-user"></i>{{ role.name }}</li>
                </ul>
              </el-scrollbar>
            </el-tab-pane>
            <el-tab-pane name="group" :lazy="true">
              <span slot="label"><i class="el-icon-connection"></i> 群组</span>
              <el-input v-model="groupFilterName" style="width:100%;" placeholder="请输入名称筛选">
                <el-button slot="append" icon="el-icon-search"></el-button>
              </el-input>
              <el-scrollbar class="scroll-category">
                <ul class="role-list">
                  <li v-if="$store.getters.param.groupUserSelect === '1'" class="role-add">
                    <el-button type="text" icon="el-icon-plus" @click="openAddGroup">新增群组</el-button>
                    <el-button type="text" icon="el-icon-setting" @click="openGroup">管理群组</el-button>
                  </li>
                  <li v-for="group in fileterGroupList" :key="group.id" @click="doQueryByGroup(group)" :class="{ selected: group.id === queryUserParam.qry_groupid }"><i class="el-icon-coordinate"></i>{{ group.name }}</li>
                </ul>
              </el-scrollbar>
            </el-tab-pane>
          </el-tabs>
        </el-col>

        <el-col :span="15">
          <el-form ref="searchForm" :inline="true" class="tl-search-form" :inline-message="true" @submit.native.prevent>
            <slot name="search" v-bind:queryUserParam="queryUserParam">
              <el-form-item>
                <el-input v-model.trim="queryUserParam.qry_namecode" clearable placeholder="输入姓名或工号搜索" @keyup.enter.native="doQueryBySearch" style="width:200px;" />
              </el-form-item>
            </slot>
            <el-button type="primary" @click="doQueryBySearch">全局搜索</el-button>
            <el-button type="primary" @click="doSelectAll" v-if="!singleSelect">全选</el-button>
          </el-form>
          <el-row>
            <el-col :span="12" style="font-size:15px;">
              检索结果（待选择区）
            </el-col>
            <el-col :span="12" style="text-align:right">
              <el-checkbox v-model="queryUserParam.qry_includeSub" label="包含所有下级" @change="queryUserBySub" />
            </el-col>
          </el-row>
          <el-scrollbar class="scroll-category">
            <el-row v-loading="isLoading" class="user-list" v-if="userList.length > 0" v-infinite-scroll="doQueryMore" infinite-scroll-disabled="noMore">
              <el-col :span="8" v-for="user in userList" :key="user.id">
                <div class="user-item" @click="addUser(user)">
                  <div class="user-img user-avater">
                    <svg-icon icon-class="user" />
                  </div>
                  <p :title="user.code">{{ user.name }}（{{ user.code }}）</p>
                  <p class="user-dept" :title="user.dispdeptid">{{ user.dispdeptid }}</p>
                  <template v-if="selectedData.findIndex((m) => m.id === user.id) > -1">
                    <div class="user-img user-shade user-hid">&nbsp;</div>
                    <div class="user-img user-check user-hid" @click.stop="removeUser(user)">
                      <svg-icon icon-class="check" />
                    </div>
                    <div class="user-img user-shade user-shade-err user-disp">&nbsp;</div>
                    <div class="user-img user-check user-disp" @click.stop="removeUser(user)">
                      <svg-icon icon-class="cross" />
                    </div>
                  </template>
                  <template v-else>
                    <div class="user-img user-shade user-disp">&nbsp;</div>
                    <div class="user-img user-check user-disp" @click.stop="addUser(user)">
                      <svg-icon icon-class="check" />
                    </div>
                  </template>
                </div>
              </el-col>
              <el-col :span="8" v-if="!noMore">
                <el-button type="primary" plain @click="doQueryMore">加载更多</el-button>
              </el-col>
            </el-row>
            <p v-else class="no-info">此条件下没有用户信息</p>
          </el-scrollbar>
        </el-col>
      </el-row>
      <el-row class="bottom-selected">
        <el-col :span="24">
          <el-row>
            <el-col :span="12">
              <h2>已选择人员({{ selectedData.length }})</h2>
            </el-col>
            <el-col :span="12" class="selected-control">
              <el-button type="text" icon="el-icon-user" @click="OneKeyAddGroup" v-if="$store.getters.param.groupUserSelect === '1'" v-show="selectedData.length > 0">一键将本次选择添加为群组</el-button>
              <el-button type="text" icon="el-icon-delete" class="btn-clear" @click="doClearAll">清空所有选择</el-button>
            </el-col>
          </el-row>
          <el-scrollbar class="scroll-selected">
            <el-row :loading="isLoading" class="user-list">
              <el-col :span="6" v-for="user in selectedData" :key="user.id">
                <div class="user-item">
                  <div class="user-img user-avater" @click.stop="removeUser(user)"><svg-icon icon-class="user" /></div>
                  <p :title="user.code">{{ user.name }}（{{ user.code }}）</p>
                  <p class="user-dept" :title="user.dispdeptid">{{ user.dispdeptid }}</p>
                  <div class="user-img user-shade user-shade-err user-disp">&nbsp;</div>
                  <div class="user-img user-check user-disp" @click.stop="removeUser(user)">
                    <svg-icon icon-class="cross" />
                  </div>
                </div>
              </el-col>
            </el-row>
          </el-scrollbar>
        </el-col>
      </el-row>
      <tl-user-group-edit ref="userGroupEditForm" v-if="$store.getters.param.groupUserSelect === '1'" @refresh="loadGroup" @loaded="groupLoad"></tl-user-group-edit>
      <div slot="footer" class="dialog-footer">
        <el-button @click="doCancelEdit">取消</el-button>
        <el-button type="primary" @click="doConfirm" v-if="!disabled">确认</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { putAction, getAction, postAction } from '@tapui/utils/http'
import tlUserGroupEdit from '@tapui/views/cbo/cboUserGroup/edit.vue'
export default {
  name: 'TlRefUser',
  components: { tlUserGroupEdit },
  data() {
    return {
      refVisible: false,
      refTitle: '用户选择',
      selectedData: [],
      activeName: 'dept',
      deptList: [],
      roleList: [],
      groupList: [],
      userList: [],
      isLoading: false,
      deptFilterName: '',
      roleFilterName: '',
      groupFilterName: '',
      deptTreeLoading: false,
      deptTreeProps: {
        label: 'name',
        children: 'children'
      },
      url: {
        queryDeptTree: '/cbo/dept/queryTreeList',
        queryRoleTree: '/cbo/role/list',
        queryGroupList: '/cbo/userGroup/list',
        queryUserList: '/sd/project/userList',
        queryDeptDataUrl: '/cbo/dept/list'
      },
      queryDeptParam: {},
      queryRoleParam: {
        sidx: 'sortcode',
        sord: 'asc',
        currentPage: 1,
        pageSize: 1000
      },
      queryGroupParam: {
        qry_available: '1', // 查询可用部门
        sidx: 'sortcode',
        sord: 'asc',
        currentPage: 1,
        pageSize: 10000
      },
      queryUserParam: {
        sidx: 'code',
        sord: 'asc',
        qry_deptid: '',
        qry_roleid: '',
        qry_namecode: '',
        qry_includeSub: false,
        currentPage: 1,
        pageSize: 14,
        totalPage: 0
      },
      disabledScrollSearch: true,
      displayUser: '',
      groupOpenType: ''
    }
  },
  props: {
    singleSelect: {
      default: false,
      type: Boolean
    },
    dataType: {
      default: 'id',
      type: String
    },
    width: {
      default: '',
      type: String
    },
    value: {
      default: '',
      type: [String, Number]
    },
    initDisplayData: {
      default: '',
      type: String
    },
    isDisplayDefaultElement: {
      default: true,
      type: Boolean
    },
    disabled: {
      default: false,
      type: Boolean
    },
    deptLazy: {
      default: false,
      type: Boolean
    },
    filterDimission: {
      default: true,
      type: Boolean
    },
    // 传入查询参数（外部）
    externalQueryParam: {
      default: function() {
        return {}
      },
      type: Object
    }
  },
  computed: {
    noMore() {
      if (this.disabledScrollSearch) {
        return true
      } else {
        return this.userList.length === 0 || this.queryUserParam.totalPage <= this.queryUserParam.currentPage
      }
    },
    fileterRoleList() {
      return this.roleList.filter((m) => m.name.indexOf(this.roleFilterName) > -1)
    },
    fileterGroupList() {
      return this.groupList.filter((m) => m.name.indexOf(this.groupFilterName) > -1)
    },
    queryUserParamFull() {
      return { ...this.queryUserParam, ...this.externalQueryParam }
    }
  },
  methods: {
    doCancelEdit() {
      this.refVisible = false
    },
    doConfirm() {
      this.displayUser = ''
      let returnData = ''
      this.selectedData.forEach((user) => {
        this.displayUser += user.name + ','
        returnData += user[this.dataType] + ','
      })
      if (this.displayUser.length > 0) {
        this.displayUser = this.displayUser.substring(0, this.displayUser.length - 1)
      }
      if (returnData.length > 0) {
        returnData = returnData.substring(0, returnData.length - 1)
      }
      this.$emit('update:initDisplayData', this.displayUser)
      this.$emit('input', returnData)
      this.$emit('confirm', this.selectedData)
      this.refVisible = false
    },
    doClearAll() {
      this.$tap
        .confirm('确定要清空选择？')
        .then((_) => {
          this.selectedData = []
        })
        .catch((_) => {})
    },
    openRefDialog() {
      if (this.disabled) {
        return
      }
      this.refVisible = true
    },
    openAddGroup() {
      this.$refs.userGroupEditForm.isAdd = true
      this.$refs.userGroupEditForm.disableEditSubmit = false
      this.$refs.userGroupEditForm.visible = true
      this.groupOpenType = ''
    },
    OneKeyAddGroup() {
      this.openAddGroup()
      this.groupOpenType = 'oneKey'
    },
    groupLoad() {
      if (this.groupOpenType === 'oneKey') {
        let usercodes = []
        let usernames = []
        this.selectedData.forEach((user) => {
          usercodes.push(user.code)
          usernames.push(user.name)
        })
        this.$refs.userGroupEditForm.model.groupusercodes = usercodes.join(',')
        this.$refs.userGroupEditForm.model.groupusernames = usernames.join(',')
      }
    },
    openGroup() {
      this.refVisible = false
      this.$nextTick((_) => {
        this.$router.push({ path: '/permission/cboUserGroup' })
      })
    },
    loadDept() {
      this.deptTreeLoading = true
      if (this.deptLazy) {
        this.deptTreeLoading = false
        return
      }
      if (this.filterDimission) {
        this.queryDeptParam.qry_enabled = 1
      }
      getAction(this.url.queryDeptTree, this.queryDeptParam).then((res) => {
        if (res.success) {
          this.deptList = []
          this.deptList = res.result.dataList
          this.deptTreeLoading = false
        }
      })
    },
    deptLazyLoad(node, resolve) {
      let queryParam = {
        sidx: 'sortcode',
        sord: 'asc',
        currentPage: 1,
        pageSize: 99999,
        totalPage: 0
      }
      if (node.key) queryParam.qry_parentid = node.key
      else queryParam.qry_parentid = 0
      if (this.filterDimission) {
        queryParam.qry_enabled = 1
      }
      getAction(this.url.queryDeptDataUrl, queryParam)
        .then((res) => {
          if (res.success) {
            return resolve(res.result.dataList)
          } else {
            this.$tap.alert(res.message, 'warning')
          }
        })
        .catch((err) => {})
    },
    loadRole() {
      getAction(this.url.queryRoleTree, this.queryRoleParam).then((res) => {
        if (res.success) {
          this.roleList = []
          this.roleList = res.result.dataList
        }
      })
    },
    /** 加载组 */
    loadGroup() {
      getAction(this.url.queryGroupList, this.queryGroupParam).then((res) => {
        if (res.success) {
          this.groupList = []
          this.groupList = res.result.dataList
        }
      })
    },
    /** 通过部门查询*/
    doQueryByDept(dept) {
      this.resetUserQueryParam()
      this.queryUserParam.qry_deptid = dept.id
      this.queryUser()
    },
    /** 通过角色查询*/
    doQueryByRole(role) {
      this.resetUserQueryParam()
      this.queryUserParam.qry_roleid = role.id
      this.queryUser()
    },
    /** 通过群组查询*/
    doQueryByGroup(group) {
      this.resetUserQueryParam()
      this.queryUserParam.qry_groupid = group.id
      this.queryUser()
    },
    doQueryBySearch() {
      this.queryUserParam.qry_deptid = ''
      this.queryUserParam.qry_roleid = ''
      this.queryUserParam.qry_groupid = ''
      this.queryUserParam.currentPage = 1
      this.queryUserParam.totalPage = 0
      this.queryUser()
    },
    doQueryMore() {
      if (!this.noMore) {
        this.queryUserParam.currentPage++
        getAction(this.url.queryUserList, this.queryUserParamFull)
          .then((res) => {
            if (res.success) {
              this.userList.push(...res.result.dataList)
              this.queryUserParam.totalPage = res.result.totalPage
            } else {
              this.$tap.alert(res.message, 'warning')
            }
          })
          .catch((err) => {})
      }
    },
    resetUserQueryParam() {
      this.disabledScrollSearch = true
      let exclude = ['sidx', 'sord', 'qry_includeSub', 'currentPage', 'pageSize', 'totalPage']
      for (let key of Object.keys(this.queryUserParam)) {
        if (!exclude.includes(key)) {
          this.queryUserParam[key] = ''
        }
      }
      this.queryUserParam.currentPage = 1
      this.queryUserParam.totalPage = 0
      if (this.filterDimission) {
        this.queryUserParam.qry_nodimission = '1'
      }
    },
    doSelectAll() {
      this.userList.forEach((user, index) => {
        if (this.selectedData.findIndex((item) => item.id === user.id) === -1) {
          this.selectedData.push(user)
        }
      })
    },
    queryUserBySub() {
      this.queryUserParam.currentPage = 1
      this.queryUserParam.totalPage = 0
      this.queryUser()
    },
    queryUser() {
      this.isLoading = true
      getAction(this.url.queryUserList, this.queryUserParamFull)
        .then((res) => {
          if (res.success) {
            this.userList = res.result.dataList
            this.queryUserParam.totalPage = res.result.totalPage
            this.disabledScrollSearch = false
          } else {
            this.$tap.alert(res.message, 'warning')
          }
          this.isLoading = false
        })
        .catch((err) => {
          this.isLoading = false
        })
    },
    tabClick(tab) {
      if (tab.name === 'dept' && this.deptList.length === 0) {
        this.loadDept()
      } else if (tab.name === 'role' && this.roleList.length === 0) {
        this.loadRole()
      } else if (tab.name === 'group' && this.groupList.length === 0) {
        // 开放了群组选择
        if (this.$store.getters.param.groupUserSelect === '1') {
          this.loadGroup()
        }
      }
    },
    addUser(user) {
      if (this.singleSelect) {
        this.selectedData = []
      }
      if (this.selectedData.findIndex((item) => item.id === user.id) === -1) {
        this.selectedData.push(user)
      }
    },
    removeUser(user) {
      this.selectedData.splice(this.selectedData.findIndex((item) => item.id === user.id), 1)
    },
    initRef() {
      // this.userList = []
      this.loadDept()
      this.resetUserQueryParam()
      this.queryDefaultSelectedValue()
    },
    queryDefaultSelectedValue() {
      this.selectedData = []
      // 打开后，加载选中值的相关数据
      let queryParam = {
        sidx: 'code',
        sord: 'asc',
        qry_codelist: '',
        qry_idlist: '',
        currentPage: 1,
        pageSize: 10000
      }
      if (this.value && this.value.toString().length > 0) {
        queryParam['qry_' + this.dataType + 'list'] = this.value
        getAction(this.url.queryUserList, queryParam)
          .then((res) => {
            if (res.success) {
              this.selectedData = res.result.dataList.filter((m) => this.value.toString().indexOf(m[this.dataType]) > -1)
            } else {
              this.$tap.alert(res.message, 'warning')
            }
          })
          .catch((err) => {})
      }
    },
    filterDept() {
      this.$refs.deptTree.filter()
    },
    filterDeptNode(value, data) {
      return data.name.indexOf(this.deptFilterName) !== -1
    },
    open() {
      this.initRef()
    }
  },
  created() {
    // this.loadDept()
  }
}
</script>
<style lang="scss">
.tl-ref-user {
  .top-category {
    .tl-tree {
      .is-leaf.el-icon-caret-right:before {
        content: '\E756';
      }
    }
    .role-list {
      list-style: none;
      padding: 0;
      margin: 0;
      li {
        list-style: none;
        cursor: pointer;
        height: 36px;
        line-height: 36px;
        i {
          padding: 6px;
        }
      }
      li:hover {
        background-color: #f5f7fa;
      }
      li.selected {
        background-color: #f5f7fa;
      }
      li.role-add {
        text-align: right;
        cursor: inherit;
        background-color: white !important;
        .el-button {
          padding: 0;
        }
      }
    }
  }
  .user-list .user-item {
    overflow: hidden;
    position: relative;
    cursor: pointer;
    .user-img {
      border-radius: 20px;
      overflow: hidden;
      width: 36px;
      height: 36px;
    }
    .user-shade {
      filter: alpha(opacity=60);
      -moz-opacity: 0.6;
      opacity: 0.6;
      background: #67c23a;
      position: absolute;
      left: 5px;
      top: 5px;
      z-index: 1;
    }
    .user-avater {
      float: left;
      margin: 5px;
      color: #409eff;
    }
    .user-check {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 2;
      margin: 5px;
      color: #fff;
      text-align: center;
    }
    .user-avater svg {
      font-size: 36px;
    }
    .user-check svg,
    .user-cross svg {
      font-size: 16px;
      margin-top: 10px;
    }
    p {
      height: 18px;
      line-height: 18px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      margin: 0;
      margin-top: 5px;
    }
    .user-dept {
      color: #aaa;
      margin: 0 0 5px 0;
    }
    .user-disp {
      display: none;
    }
    .user-hid {
      display: block;
    }
    .user-shade-err {
      background: #f56c6c;
    }
  }
  .user-item:hover .user-disp {
    display: block;
  }
  .user-item:hover .user-hid {
    display: none;
  }
  .user-list > .el-col {
    margin-top: 10px;
  }
}
</style>
